package org.water.garden.msn.service;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.water.garden.R;
import org.water.garden.activity.account.AccountList;
import org.water.garden.core.Intents;

import net.sf.jml.MsnContact;
import net.sf.jml.MsnList;
import net.sf.jml.MsnMessenger;
import net.sf.jml.MsnSwitchboard;
import net.sf.jml.MsnUserStatus;
import net.sf.jml.event.MsnAdapter;
import net.sf.jml.message.MsnControlMessage;
import net.sf.jml.message.MsnDatacastMessage;
import net.sf.jml.message.MsnInstantMessage;
import net.sf.jml.message.MsnSystemMessage;
import net.sf.jml.message.MsnUnknownMessage;
import android.app.Notification;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.Im;
import android.provider.Im.Contacts;
import android.provider.Im.ContactsColumns;
import android.util.Log;

public class MsnActionAdapter extends MsnAdapter {

	private MsnService service;
	private MsnMessenger messenger;
	protected int accountId;
	protected int providerId;

	public MsnActionAdapter(MsnService msnService, MsnMessenger messenger, int accountId, int providerId) {
		this.service = msnService;
		this.messenger = messenger;
		
		this.accountId = accountId;
		this.providerId = providerId;
	}

	public MsnService getService() {
		return service;
	}

	public void setService(MsnService service) {
		this.service = service;
	}

	private static void msg(Object obj) {
		SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm");
		if (obj instanceof Throwable)
			Log.e("MsnActionAdapter", "[" + sdf.format(new Date()) + "] " + obj);
		else
			Log.i("MsnActionAdapter", "[" + sdf.format(new Date()) + "] " + obj);
	}

	public void instantMessageReceived(MsnSwitchboard switchboard, MsnInstantMessage message, MsnContact mc) {
		msg(mc.getDisplayName() + "(" + mc.getEmail() + ") to me : " + message.getContent());

		ContentValues values = new ContentValues();
		values.put(Im.MessagesColumns.PROVIDER, providerId);
		values.put(Im.MessagesColumns.TYPE, Im.MessageType.INCOMING);
		values.put(Im.MessagesColumns.ACCOUNT, accountId);
		values.put(Im.MessagesColumns.CONTACT, mc.getEmail().toString());

		values.put(Im.MessagesColumns.BODY, message.getContent());
		values.put(Im.MessagesColumns.DATE, (new Date()).getTime());

		Uri messageUri = service.getContentResolver().insert(Im.Messages.CONTENT_URI, values);
		service.broadcastIntent(new Intent(Intents.NEW_MESSAGE, messageUri));
	}

	public void systemMessageReceived(MsnMessenger messenger, MsnSystemMessage message) {
		msg(messenger + " recv system message " + message);
	}

	public void controlMessageReceived(MsnSwitchboard switchboard, MsnControlMessage message, MsnContact contact) {
		msg(contact.getFriendlyName() + "is typing");
	}

	public void exceptionCaught(MsnMessenger messenger, Throwable throwable) {
		msg(messenger + throwable.toString());
		StringWriter stringWriter = new StringWriter();
		PrintWriter writer = new PrintWriter(stringWriter);
		throwable.printStackTrace(writer);
		msg(stringWriter.toString());
	}

	public void loginCompleted(MsnMessenger messenger) {
		msg(messenger.getOwner().getDisplayName() + "login success");

		service.notifyInfo(new Notification(service, 
				R.drawable.msn_notify, 
                service.getText(R.string.msn_account_login),
				System.currentTimeMillis(), 
				service.getText(R.string.msn_account_login),
				service.getText(R.string.msn_account_login),
				new Intent(service, AccountList.class), 
				R.drawable.msn_notify,
				service.getText(R.string.msn_account_login),
				new Intent(service, AccountList.class)));
	}

	public void logout(MsnMessenger messenger) {
		msg(messenger + " logout");

		service.notifyInfo(new Notification(service, 
				R.drawable.msn_offline, 
				service.getText(R.string.msn_account_logout),
				System.currentTimeMillis(), 
				service.getText(R.string.msn_account_logout),
				service.getText(R.string.msn_account_logout),
				new Intent(service, AccountList.class), 
				R.drawable.msn_offline,
				service.getText(R.string.msn_account_logout),
				new Intent(service, AccountList.class)));
		
		service.cancelNotify();
	}

	public void datacastMessageReceived(MsnSwitchboard switchboard, MsnDatacastMessage message, MsnContact friend) {
		msg(switchboard + " recv datacast message " + message);
		switchboard.sendMessage(message, false);
	}

	public void unknownMessageReceived(MsnSwitchboard switchboard, MsnUnknownMessage message, MsnContact friend) {
		msg(switchboard + " recv unknown message " + message);
	}

	public void contactListInitCompleted(MsnMessenger messenger) {
		MsnContact[] mcs = messenger.getContactList().getContactsInList(MsnList.AL);
		Cursor cur = null;
		
		for (MsnContact mc : mcs) {
			cur = service.getContentResolver().query(Contacts.CONTENT_URI, new String[]{Contacts._ID}, 
					Contacts.USERNAME + "=?", new String[]{mc.getEmail().toString()}, null);
			Long contactId = null;
			if(!cur.first()){
				ContentValues values = new ContentValues();
				values.put(Contacts.ACCOUNT, accountId);
				values.put(Contacts.PROVIDER, providerId);
				values.put(ContactsColumns.TYPE, ContactsColumns.TYPE_NORMAL);
				values.put(ContactsColumns.SUBSCRIPTION_STATUS, ContactsColumns.SUBSCRIPTION_STATUS_NONE);
				values.put(ContactsColumns.SUBSCRIPTION_TYPE, ContactsColumns.SUBSCRIPTION_TYPE_BOTH);
				
				values.put(Contacts.NICKNAME, mc.getDisplayName());
				values.put(Contacts.USERNAME, mc.getEmail().toString());

				Uri contactUri = service.getContentResolver().insert(Contacts.CONTENT_URI, values);
				contactId = new Long(contactUri.getLastPathSegment());
			} else {
				contactId = cur.getLong(0);
			}
			if(cur != null) cur.close();
			
			if(contactId != null){
				cur = service.getContentResolver().query(Im.Presence.CONTENT_URI, new String[]{
						Im.Presence._ID, Im.Presence.PRESENCE_STATUS, Im.Presence.PRESENCE_CUSTOM_STATUS}, 
						Im.Presence.CONTACT_ID + "=?", new String[]{contactId.toString()}, null);
				
				String status = mc.getStatus().getStatus();
				int mode = Im.Presence.OFFLINE;
				if(status.equals(MsnUserStatus.ONLINE.getStatus())){
					mode = Im.Presence.AVAILABLE;
				} else if(status.equals(MsnUserStatus.OFFLINE.getStatus())){
					mode = Im.Presence.OFFLINE;
				} else {
					mode = Im.Presence.IDLE;
				}
				
				if(cur.first()){
					cur.updateInt(1, mode);
					cur.updateString(2, mc.getPersonalMessage());
					cur.commitUpdates();
				} else {
					ContentValues values = new ContentValues();
					values.put(Im.Presence.CONTACT_ID, contactId);
					values.put(Im.Presence.PRESENCE_STATUS, mode);
					values.put(Im.Presence.PRESENCE_CUSTOM_STATUS, mc.getPersonalMessage());
					values.put(Im.Presence.PRIORITY, 0);
					
					service.getContentResolver().insert(Im.Presence.CONTENT_URI, values);
				}
				if(cur != null) cur.close();
			}
		}

		if(cur != null) cur.close();
		
		msg("contract-init" + mcs.length);
	}

	@Override
	public void contactStatusChanged(MsnMessenger messenger, MsnContact mc) {

		Cursor cur = service.getContentResolver().query(Contacts.CONTENT_URI, new String[]{Contacts._ID}, 
				Contacts.USERNAME + "=?", new String[]{mc.getEmail().toString()}, null);
		
		if(cur.first()){
			Long contactId = cur.getLong(0);	
			
			Cursor mcur = service.getContentResolver().query(Im.Presence.CONTENT_URI, new String[]{
					Im.Presence._ID, Im.Presence.PRESENCE_STATUS, Im.Presence.PRESENCE_CUSTOM_STATUS}, 
					Im.Presence.CONTACT_ID + "=?", new String[]{contactId.toString()}, null);
			
			String status = mc.getStatus().getStatus();
			int mode = Im.Presence.OFFLINE;
			if(status.equals(MsnUserStatus.ONLINE.getStatus())){
				mode = Im.Presence.AVAILABLE;
			} else if(status.equals(MsnUserStatus.OFFLINE.getStatus())){
				mode = Im.Presence.OFFLINE;
			} else {
				mode = Im.Presence.IDLE;
			}
			
			if(mcur.first()){
				mcur.updateInt(1, mode);
				mcur.updateString(2, mc.getPersonalMessage());
				mcur.commitUpdates();
			} else {
				ContentValues values = new ContentValues();
				values.put(Im.Presence.CONTACT_ID, contactId);
				values.put(Im.Presence.PRESENCE_STATUS, mode);
				values.put(Im.Presence.PRESENCE_CUSTOM_STATUS, mc.getPersonalMessage());
				values.put(Im.Presence.PRIORITY, 0);
				
				service.getContentResolver().insert(Im.Presence.CONTENT_URI, values);
			}
			cur.commitUpdates();
		}
		if(cur != null) cur.close();
	}

	public void contactListSyncCompleted(MsnMessenger messenger) {
		// listContacts(MsnUserStatus.ONLINE);
	}

	public void switchboardClosed(MsnSwitchboard switchboard) {
		msg("switchboardStarted " + switchboard);
	}

	public void switchboardStarted(MsnSwitchboard switchboard) {
		msg("switchboardStarted " + switchboard);
	}
}
